/********************************************************************************
* @file    ls_gpio.h
* @author  jianqiang.xue
* @version V1.3.0
* @date    2023-06-04
* @brief   业务类--GPIO定义
********************************************************************************/
#ifndef __LS_GPIO_H
#define __LS_GPIO_H
#define LS_IO_VERSION "CX32L003_通用模板_TSSOP20"
#include "bsp_gpio.h"
#include "bsp_exti.h"
#include "bsp_uart.h"
#include "bsp_adc.h"
#include "bsp_i2c.h"
#include "bsp_tim.h"

#include "cx32l003_hal.h"
#include "cx32l003_hal_def.h"

/* GPIO_EXTI_INT_EDGE;             // 中断类型 边沿触发
    GPIO_EXTI_INT_LOWFALL;  // 下降沿触发中断
    GPIO_EXTI_INT_HIGHRISE; // 上升沿触发中断
    GPIO_EXTI_INT_FALLRISE; // 下降沿上升沿都触发中断
GPIO_EXTI_INT_LEVEL;            // 中断类型 电平触发
    GPIO_EXTI_INT_LOWFALL;  // 低电平触发中断
    GPIO_EXTI_INT_HIGHRISE; // 高电平触发中断 */

#define GPIO_CLK(GPIO)                              (RCC_HCLKEN_##GPIO##CKEN)
#define GPIO_APBx                                   (0)
/************************************GPIO***********************************/
#define LS_IO_NUM                                   (21) // io+1, 比如20pin,则填写21,多一个数组0占位，不然pin号无法对应。
/* Public Struct -------------------------------------------------------------*/
// #define LS_IO_EXTEND_SUPPORT

#ifdef LS_IO_EXTEND_SUPPORT
typedef uint64_t support_l;
#else
typedef uint32_t support_l;
#endif

union io_support_t {
    support_l val; // 对外值
    struct {
        support_l swo                : 1;

        support_l adc0_ch0           : 1;
        support_l adc0_ch1           : 1;
        support_l adc0_ch2           : 1;
        support_l adc0_ch3           : 1;
        support_l adc0_ch4           : 1;
        support_l adc0_ch5           : 1;
        support_l adc0_ch6           : 1;

        support_l tim1_ch1           : 1; // PWM0
        support_l tim1_ch2           : 1; // PWM1
        support_l tim1_ch3           : 1; // PWM2
        support_l tim1_ch4           : 1; // PWM3
        support_l tim2_ch1           : 1; // PWM4
        support_l tim2_ch2           : 1; // PWM5
        support_l tim2_ch3           : 1; // PWM6
        support_l tim2_ch4           : 1; // PWM7

        support_l uart0_tx           : 1;
        support_l uart0_rx           : 1;
        support_l uart1_tx           : 1;
        support_l uart1_rx           : 1;
        support_l uart2_tx           : 1;
        support_l uart2_rx           : 1;

        support_l i2c0_scl           : 1; // 硬件IIC
        support_l i2c0_sda           : 1;
        support_l i2c_scl_soft       : 1; // 软件IIC
        support_l i2c_sda_soft       : 1;

        support_l spi0_clk           : 1;
        support_l spi0_mosi          : 1;
        support_l spi0_miso          : 1;
        support_l spi0_nss           : 1;

#ifdef LS_IO_EXTEND_SUPPORT
        support_l reserve            : 34;
#else
        support_l reserve            : 2;
#endif
    } bit;
};

typedef enum { // IO 引脚类型
    IO_TYPE_IN_NULL = 0, // 无上下拉
    IO_TYPE_IN_PULLUP,   // 输入，上拉
    IO_TYPE_IN_PULLDOWN, // 输入，下拉

    IO_TYPE_OUT_PP,      // 推免输出
    IO_TYPE_OUT_OD,      // 开漏输出
    // 中断输入
    IO_TYPE_INIRQ_LEVEL_LOW,     // 电平触发-低电平
    IO_TYPE_INIRQ_LEVEL_HIGH,    // 电平触发-高电平
    IO_TYPE_INIRQ_EDGE_LOWFALL,  // 边沿触发-下降沿
    IO_TYPE_INIRQ_EDGE_HIGHRISE, // 边沿触发-上降沿
    IO_TYPE_INIRQ_EDGE_FALLRISE, // 边沿触发-任意电平变化

    IO_TYPE_SWO,          // 烧录脚
    IO_TYPE_KEY,          // 按键
    IO_TYPE_MATRIX_KEY_X, // 矩阵键盘X轴
    IO_TYPE_MATRIX_KEY_Y, // 矩阵键盘Y轴
    IO_TYPE_W2812X,

    IO_TYPE_ADC0_CH0, // ADC0_0
    IO_TYPE_ADC0_CH1, // ADC0_1
    IO_TYPE_ADC0_CH2, // ADC0_2
    IO_TYPE_ADC0_CH3, // ADC0_3
    IO_TYPE_ADC0_CH4, // ADC0_4
    IO_TYPE_ADC0_CH5, // ADC0_5
    IO_TYPE_ADC0_CH6, // ADC0_6

    IO_TYPE_TIM1_CH1, // PWM0
    IO_TYPE_TIM1_CH2, // PWM1
    IO_TYPE_TIM1_CH3, // PWM2
    IO_TYPE_TIM1_CH4, // PWM3
    IO_TYPE_TIM2_CH1, // PWM4
    IO_TYPE_TIM2_CH2, // PWM5
    IO_TYPE_TIM2_CH3, // PWM6
    IO_TYPE_TIM2_CH4, // PWM7

    IO_TYPE_UART0_TX,   // 串口0,TX
    IO_TYPE_UART0_RX,   // 串口0,RX
    IO_TYPE_UART1_TX,   // 串口1,TX
    IO_TYPE_UART1_RX,   // 串口1,RX
    IO_TYPE_UART2_TX,   // 串口2,TX
    IO_TYPE_UART2_RX,   // 串口2,RX

    IO_TYPE_I2C0_SCL,   // 硬件IIC0
    IO_TYPE_I2C0_SDA,   // 硬件IIC0
    IO_TYPE_I2C_SCL_SOFT, // 软件IIC
    IO_TYPE_I2C_SDA_SOFT, // 软件IIC

    IO_TYPE_SPI0_CLK,     // SPI0_时钟
    IO_TYPE_SPI0_MOSI,    // SPI0_主机输出
    IO_TYPE_SPI0_MISO,    // SPI0_主机输入
    IO_TYPE_SPI0_NSS,     // SPI0_片选

    IO_TYPE_MAX,
} io_type_t;

typedef struct __attribute__((packed, aligned(1))) {
    bsp_gpio_t io; // 引脚配置(时钟/中断号)
    union io_support_t support; // 引脚支持类型
    io_type_t type; // 引脚默认类型
} ls_io_cfg_t; // 芯片默认配置

extern const ls_io_cfg_t g_io_cfg[LS_IO_NUM];
void ls_gpio_init(void);
#ifdef LS_IO
#include "ls_key.h"
const ls_io_cfg_t g_io_cfg[LS_IO_NUM] = {
    {{(NULL),  (0),          NULL,            (0)         , (0)}, {0x00000000}, IO_TYPE_MAX},
    {{(GPIOD), (GPIO_PIN_4), GPIO_CLK(GPIOD), (GPIOD_IRQn), (0)}, {0x03020100}, IO_TYPE_KEY},
    {{(GPIOD), (GPIO_PIN_5), GPIO_CLK(GPIOD), (GPIOD_IRQn), (0)}, {0x10458040}, IO_TYPE_IN_PULLUP},
    {{(GPIOD), (GPIO_PIN_6), GPIO_CLK(GPIOD), (GPIOD_IRQn), (0)}, {0x088A2280}, IO_TYPE_ADC0_CH6},
    {{(NULL),  (0),          NULL,            (0),          (0)}, {0x00000000}, IO_TYPE_MAX},
    {{(GPIOA), (GPIO_PIN_1), GPIO_CLK(GPIOA), (GPIOA_IRQn), (0)}, {0x074A0000}, IO_TYPE_UART0_RX},
    {{(GPIOA), (GPIO_PIN_2), GPIO_CLK(GPIOA), (GPIOA_IRQn), (0)}, {0x23452400}, IO_TYPE_UART0_TX},
    {{(NULL),  (0),          NULL,            (0),          (0)}, {0x00000000}, IO_TYPE_MAX},
    {{(NULL),  (0),          NULL,            (0),          (0)}, {0x00000000}, IO_TYPE_MAX},
    {{(NULL),  (0),          NULL,            (0),          (0)}, {0x00000000}, IO_TYPE_MAX},
    {{(GPIOA), (GPIO_PIN_3), GPIO_CLK(GPIOA), (GPIOA_IRQn), (0)}, {0x20204000}, IO_TYPE_TIM2_CH3},
    {{(GPIOB), (GPIO_PIN_5), GPIO_CLK(GPIOB), (GPIOB_IRQn), (0)}, {0x04821000}, IO_TYPE_I2C0_SDA},
    {{(GPIOB), (GPIO_PIN_4), GPIO_CLK(GPIOB), (GPIOB_IRQn), (0)}, {0x23410000}, IO_TYPE_I2C0_SCL},
    {{(GPIOC), (GPIO_PIN_3), GPIO_CLK(GPIOC), (GPIOC_IRQn), (0)}, {0x00844404}, IO_TYPE_UART1_TX},
    {{(GPIOC), (GPIO_PIN_4), GPIO_CLK(GPIOC), (GPIOC_IRQn), (0)}, {0x00488808}, IO_TYPE_UART1_RX},
    {{(GPIOC), (GPIO_PIN_5), GPIO_CLK(GPIOC), (GPIOC_IRQn), (0)}, {0x04100000}, IO_TYPE_OUT_PP},
    {{(GPIOC), (GPIO_PIN_6), GPIO_CLK(GPIOC), (GPIOC_IRQn), (0)}, {0x08208102}, IO_TYPE_ADC0_CH0},
    {{(GPIOC), (GPIO_PIN_7), GPIO_CLK(GPIOC), (GPIOC_IRQn), (0)}, {0x10080201}, IO_TYPE_SWO},
    {{(GPIOD), (GPIO_PIN_1), GPIO_CLK(GPIOD), (GPIOD_IRQn), (0)}, {0x00040001}, IO_TYPE_SWO},
    {{(GPIOD), (GPIO_PIN_2), GPIO_CLK(GPIOD), (GPIOD_IRQn), (0)}, {0x10100210}, IO_TYPE_TIM1_CH2},
    {{(GPIOD), (GPIO_PIN_3), GPIO_CLK(GPIOD), (GPIOD_IRQn), (0)}, {0x08012020}, IO_TYPE_TIM2_CH2},
};

__weak void app_io_exti_cb(void *gpiox, uint16_t gpio_pin) {
// [中断回调START]
// [中断回调END]
}

// [按键回调START]
extern void power_key(uint8_t event);
// [按键回调END]

void ls_gpio_init(void) {
// [初始化START]
    io_set_in_mode(2, IO_PULLUP);
    io_set_out_mode(15, IO_OUT_PP);
    bsp_tim1_drive_pwm_init(0, 19, 0, 0);

    bsp_tim2_drive_pwm_init(0, 20, 10, 0);

    io_cfg_as_adc0(3);
    io_cfg_as_adc0(16);
    bsp_adc0_init();

    ls_key_reg(1, power_key);
    ls_key_init(NULL);

    bsp_uart_init(BSP_UART_0, LS_UART0_BAUD_RATE, 6, 5);

    bsp_uart_init(BSP_UART_1, LS_UART1_BAUD_RATE, 13, 14);

    bsp_i2c_init(I2C_BUS0, 12, 11);
// [初始化END]
}
#endif // __LS_IO_END


// [引脚宏名称START]
#define POWER_KEY (1) // 电源键
// [引脚宏名称END]
#endif  // __LS_GPIO_H